package com.ygqh.baby.service.impl;

import com.foxinmy.weixin4j.util.NameValue;
import com.ygqh.baby.ao.*;
import com.ygqh.baby.dao.ChatRecordDao;
import com.ygqh.baby.model.ChatRecord;
import com.ygqh.baby.model.YgUserModel;
import com.ygqh.baby.service.ChatRecordService;
import com.ygqh.baby.service.SmsService;
import com.ygqh.baby.utils.CommonUtil;
import com.ygqh.baby.utils.DateConvertUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

@Service
public class ChatRecordServiceImpl implements ChatRecordService {

	private final Logger logger = LoggerFactory.getLogger(this.getClass());
	private final ExecutorService executorService = Executors.newFixedThreadPool(3);
	
	@Autowired
	private ChatRecordDao chatRecordDao;
	@Autowired
	private BaseWxMpMessageService baseWxMpMessageService;
	@Autowired
	private SmsService smsService;

	@Value("${user.chaturl}")
	private String userChatUrl;

	@Override
	public ResultSet<ChatRecord> search(List<Long> userIdList, String q, Integer page) {
		Map<String, Object> conditions = new HashMap<>();
		if (CollectionUtils.isNotEmpty(userIdList)) {
			conditions.put("userId", userIdList);
		}
		if (StringUtils.isNotBlank(q)) {
			conditions.put("detailContent", "^.*" + q + ".*$");
		}
		Date endTime = DateConvertUtils.addDay(DateConvertUtils.getDateEnd(new Date()), -31 * (page - 1));
		/*Date endTime = DateConvertUtils.addDay(DateConvertUtils.getDateEnd(new Date()), -1 * (page - 1));*/
		Map<String, Object> _map = new HashMap<>();
		_map.put("lte", endTime);
		Map<String, Object> map = new HashMap<>();
		map.put("createTime", _map);
		conditions.put("compare", map);
		Long count = chatRecordDao.getEntityCount(conditions);
		if (count == 0) {
			ResultSet<ChatRecord> rs = new ResultSet<>();
			rs.setResult(new ArrayList<>());
			rs.setPage(page);
			return rs;
		}
		return this.findUserRecordList(conditions, page);
	}
	
	private ResultSet<ChatRecord> findUserRecordList(Map<String, Object> conditions, Integer page) {
		if (page == null) {
			page = 1;
		}
		Date endTime = DateConvertUtils.getDateEnd(DateConvertUtils.addDay(new Date(), -31 * (page - 1)));
		Date startTime = DateConvertUtils.getDateStart(DateConvertUtils.addDay(endTime, -30));
		/*Date endTime = DateConvertUtils.getDateEnd(DateConvertUtils.addDay(new Date(), -1 * (page - 1)));
		Date startTime = DateConvertUtils.getDateStart(endTime);*/
		Map<String, Object> _map = new HashMap<>();
		_map.put("lte", endTime);
		_map.put("gte", startTime);
		Map<String, Object> map = new HashMap<>();
		map.put("createTime", _map);
		conditions.put("compare", map);
		Map<String, String> orders = new HashMap<>();
		orders.put("createTime", OrderDirection.asc.name());
		List<ChatRecord> entityList = chatRecordDao.getEntityList(conditions, orders);
		if (CollectionUtils.isEmpty(entityList)) {
			return findUserRecordList(conditions, page + 1);
		}
		ResultSet<ChatRecord> rs = new ResultSet<>();
		rs.setResult(entityList);
		rs.setPage(page);
		return rs;
	}

	@Override
	public List<ChatRecord> findUserRecordList(List<Long> userIdList, String q) {
		Map<String, Object> conditions = new HashMap<>();
		if (CollectionUtils.isNotEmpty(userIdList)) {
			conditions.put("userId", userIdList);
		}
		if (StringUtils.isNotBlank(q)) {
			Map<String, Object> map = new HashMap<>();
			map.put("userNickName", "^.*" + q + ".*$");
			map.put("detailContent", "^.*" + q + ".*$");
			conditions.put("ors", map);
		}
		conditions.put("status", DataStatus.Valid);
		Map<String, String> orders = new HashMap<>();
		orders.put("createTime", OrderDirection.asc.name());
		return chatRecordDao.getEntityList(conditions, orders);
	}

	@Override
	public Message updateChatRecordToRead(String sendUserId, String receiveUserId, YgUserModel currentUser) {
		if (StringUtils.isBlank(receiveUserId) && StringUtils.isBlank(sendUserId)) {
			return Message.error("userId is Null");
		}
		Map<String, Object> updateMap = new HashMap<>();
		updateMap.put("isRead", Boolean.TRUE);
		updateMap.put("updateTime", new Date());
		updateMap.put("updateBy", currentUser.getNickName());
		Map<String, Object> conditions = new HashMap<>();
		if (StringUtils.isNotBlank(receiveUserId)) {
			conditions.put("receiveUserId", receiveUserId);
		}
		if (StringUtils.isNotBlank(sendUserId)) {
			conditions.put("sendUserId", sendUserId);
		}
		chatRecordDao.updateEntities(updateMap, conditions);
		return Message.success(1);
	}

	@Override
	public void save(ChatRecord chatRecord) {
		chatRecordDao.saveEntity(chatRecord);
	}
	
	@Override
	public List<ChatRecord> findUserRecordList(List<Long> userIdList, String q, QueryInfo queryInfo) {
		Map<String, Object> conditions = new HashMap<>();
		if (CollectionUtils.isNotEmpty(userIdList)) {
			conditions.put("userId", userIdList);
		}
		if (StringUtils.isNotBlank(q)) {
			conditions.put("detailContent", "^.*" + q + ".*$");
		}
		Map<String, String> orders = new HashMap<>();
		orders.put("createTime", OrderDirection.desc.name());
		if (queryInfo != null) {
			queryInfo.setLimit(queryInfo.getEnd() - queryInfo.getStart());
		}
		List<ChatRecord> pageEntityList = chatRecordDao.getPageEntityList(queryInfo, conditions, orders);
		if (CollectionUtils.isEmpty(pageEntityList)) {
			return new ArrayList<>();
		}
		pageEntityList.sort(Comparator.comparing(ChatRecord::getCreateTime));
		return pageEntityList;
	}

	@Override
	public void sendTemplateMessage(String openId, ChatRecord chatRecord) {
		executorService.execute(() -> {
			if (StringUtils.isBlank(openId)) {
				return;
			}
			String sendContent = getWaitingSendContent(chatRecord);
			if (StringUtils.isBlank(sendContent)) {
				return;
			}
			Map<String, NameValue> contentMap = new HashMap<>();
			contentMap.put("first", new NameValue("#323232", "您的问题有新的回复了"));
			contentMap.put("keyword1", new NameValue("#323232", "壹果微信商城"));
			contentMap.put("keyword2", new NameValue("#173177", sendContent));
			contentMap.put("keyword3", new NameValue("#323232", DateConvertUtils.formatDateTime(chatRecord.getCreateTime())));
			//发送微信模板消息
			baseWxMpMessageService.sendTemplateMessage(WxMessageType.ChatRecord, openId, userChatUrl, contentMap);
		});
	}

	@Override
	public void sendSms(String userName, ChatRecord chatRecord) {
		executorService.execute(() -> {
			if(!CommonUtil.isChinaPhoneLegal(userName)){
				return;
			}
			String sendContent = getWaitingSendContent(chatRecord);
			if (StringUtils.isBlank(sendContent)) {
				return;
			}
			smsService.sendSms(userName, "您有新的留言,请登录壹果微信商城进行查看");
		});
	}

	private String getWaitingSendContent(ChatRecord chatRecord) {
		if (chatRecord == null || StringUtils.isBlank(chatRecord.getDetailContent())) {
			return null;
		}
		String detailContent = chatRecord.getDetailContent();
		if (detailContent.startsWith("<br>")) {
			detailContent = detailContent.substring(4);
		}
		if (detailContent.endsWith("<br>")) {
			detailContent = detailContent.substring(0, detailContent.length() - 4);
		}
		return detailContent.replaceAll("<br>", "\n").replaceAll("<img[^>]*((?!>).)>","").trim();
	}

	@Override
	public List<ChatRecord> findUserRecordList(Map<String, Object> conditions, Map<String, String> orders) {
		return chatRecordDao.getEntityList(conditions, orders);
	}

	@Override
	public ResultSet<Map<String, Object>> report(QueryInfo queryInfo) {
		List<Map<String, Object>> list = chatRecordDao.report(queryInfo);
		Long count = chatRecordDao.countReport();
		return new ResultSet<>(count, list);
	}

	@Override
	public List<Map<String, Object>> reportByCustomer(Date date) {
		List<Map<String, Object>> dataList = new ArrayList<>();
		List<ChatRecord> recordListByDate = this.findUserRecordListByDate(date, null);
		// 按客服id分组
		Map<String, List<ChatRecord>> recordMapGroupBySendUserId = recordListByDate.stream().filter(o -> !o.getUserId().toString().equals(o.getSendUserId()))
				.collect(Collectors.groupingBy(ChatRecord::getSendUserId));
		for (Map.Entry<String, List<ChatRecord>> entry : recordMapGroupBySendUserId.entrySet()) {
			Map<String, Object> data = new HashMap<>();
			data.put("customerUserId", entry.getKey());
			List<ChatRecord> list = entry.getValue();
			data.put("customerUserName", list.get(0).getSendNickName());
			int count = list.stream().collect(Collectors.groupingBy(ChatRecord::getUserId)).size();
			data.put("count", count);
			dataList.add(data);
		}
		return dataList;
	}

	@Override
	public List<ChatRecord> findUserRecordListByDate(Date date, Boolean isSort) {
		return findUserRecordListByDate(DateConvertUtils.getDateStart(date), DateConvertUtils.addDay(date, 1), isSort);
	}

	@Override
	public List<ChatRecord> findUserRecordListByDate(Date startTime, Date endTime, Boolean isSort) {
		Map<String, Object> conditions = new HashMap<>();
		conditions.put("status", DataStatus.Valid);
		Map<String, Object> createTimeMap = new HashMap<>();
		createTimeMap.put("gte", startTime);
		createTimeMap.put("lt", endTime);
		Map<String, Object> compareMap = new HashMap<>();
		compareMap.put("createTime", createTimeMap);
		conditions.put("compare", compareMap);
		Map<String, String> orders = null;
		if (isSort != null && isSort) {
			orders = new HashMap<>();
			orders.put("createTime", "desc");
		}
		return this.findUserRecordList(conditions, orders);
	}
	
}
